﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using System.Web.Optimization;

namespace Day27Auth.Framework
{
    public class VirtualMethodBundle : ScriptBundle
    {
        private List<VirtualFile> _virtualContent = new List<VirtualFile>();
        private string _path;
        public VirtualMethodBundle(string path) : base (path)
        {
            _path = path;
        }

        public override Bundle Include(params string[] virtualPaths)
        {
            return base.Include(virtualPaths);
        }

        public Bundle Include<TController>(Expression<Func<TController, Func<ActionResult>>> action) where TController : Controller, new()
        {
            UnaryExpression unaryExpr = (UnaryExpression)action.Body;
            MethodCallExpression methodCallExpr = (MethodCallExpression)unaryExpr.Operand;
            ConstantExpression constantExpr = (ConstantExpression)methodCallExpr.Object;
            
            MemberInfo memberInfo = (MemberInfo)constantExpr.Value;

            string methodName = memberInfo.Name;

            TController c = new TController();
            var cmethod = c.GetType().GetMethod(methodName);
            ActionResult r = (ActionResult)cmethod.Invoke(c, null);
            string viewName = string.Empty;
            
            if (r is ViewResultBase)
            {
                viewName = (r as ViewResultBase).ViewName;
            }

            string cname = c.GetType().Name.Replace("Controller", "");

            //Build URL from Controller and Action
            string path = string.Format("~/Views/{0}/{1}.cshtml", cname, viewName);
            return base.Include(path);
        }

        public override IEnumerable<BundleFile> EnumerateFiles(BundleContext context)
        {
            foreach (var file in base.EnumerateFiles(context))
            {
                if (file.VirtualFile.VirtualPath.Contains(".cshtml"))
                {
                    Bundle bundle = (context.BundleCollection
                        .Where(b => b.Path == context.BundleVirtualPath)
                        .FirstOrDefault());

                    ActionVirtualFile avf = new ActionVirtualFile(file.VirtualFile.VirtualPath);
                    yield return new BundleFile(_path, avf);
                }
                else
                {
                    yield return file;
                }
                
            }
        }
    }
}